﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Aga.Controls.Tree;

namespace UnrealDebugger.Panels
{
    class UserWatchPanel : WatchPanel
    {
        private string _userWatches = "";

        private System.Windows.Forms.TextBox textBoxAddWatch;
        private System.Windows.Forms.Label labelAddWatch;
        private ContextMenuStrip contextMenuStripUserWatch;
        private System.ComponentModel.IContainer components;
        private ToolStripMenuItem addUserWatchToolStripMenuItem;
        private ToolStripMenuItem removeWatchToolStripMenuItem;
        private ToolStripMenuItem clearAllWatchesToolStripMenuItem;
        private System.Windows.Forms.Panel panelAddWatch;
    
        public UserWatchPanel()
            : base()
        {
            InitializeComponent();
            this.Text = "User Watches";

            UnrealDebuggerIDE.Instance.OnReadUserData += new UnrealDebuggerIDE.ReadUserDataDelegate(OnReadUserData);
            UnrealDebuggerIDE.Instance.OnWriteUserData += new UnrealDebuggerIDE.WriteUserDataDelegate(OnWriteUserData);
        }

        void OnReadUserData(SerializableDictionary<string, string> userData)
        {
            if (userData.ContainsKey("UserWatches"))
            {
                string[] tokens = userData["UserWatches"].Split(new char[] { '#' }, StringSplitOptions.RemoveEmptyEntries);

                foreach (string token in tokens)
                {
                    UnrealDebuggerIDE.Commands.AddWatch(token);
                }
            }
        }

        void OnWriteUserData(SerializableDictionary<string, string> userData)
        {
            userData["UserWatches"] = this._userWatches;
        }

        public void FocusInput()
        {
            this.textBoxAddWatch.SelectAll();
            this.textBoxAddWatch.Focus();
        }

        #region Debugger Interface

        public override void UnlockList(UnlockListAction.WatchList buffer)
        {
            base.UnlockList(buffer);
            this.treeViewWatches.Model = new WatchTreeModel(buffer);

            this._userWatches = "";

            foreach (TreeNodeAdv node in this.treeViewWatches.Root.Children)
            {
                WatchNode watchNode = node.Tag as WatchNode;
                if (watchNode != null) { this._userWatches += watchNode.Variable + "#"; }
            }
        }

        #endregion

        protected override ContextMenuStrip SelectContextMenuForNode(TreeNodeAdv node)
        {
            this.addUserWatchToolStripMenuItem.Enabled = (node != null);
            this.removeWatchToolStripMenuItem.Enabled = (node != null) && (node.Level == 1);
            return this.contextMenuStripUserWatch;
        }

        private void InitializeComponent()
        {
            this.components = new System.ComponentModel.Container();
            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(UserWatchPanel));
            this.panelAddWatch = new System.Windows.Forms.Panel();
            this.textBoxAddWatch = new System.Windows.Forms.TextBox();
            this.labelAddWatch = new System.Windows.Forms.Label();
            this.contextMenuStripUserWatch = new System.Windows.Forms.ContextMenuStrip(this.components);
            this.addUserWatchToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.removeWatchToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.clearAllWatchesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.panelAddWatch.SuspendLayout();
            this.contextMenuStripUserWatch.SuspendLayout();
            this.SuspendLayout();
            // 
            // treeViewWatches
            // 
            this.treeViewWatches.AllowDrop = true;
            this.treeViewWatches.Size = new System.Drawing.Size(717, 242);
            this.treeViewWatches.DragDrop += new System.Windows.Forms.DragEventHandler(this.treeViewWatches_DragDrop);
            this.treeViewWatches.DragEnter += new System.Windows.Forms.DragEventHandler(this.treeViewWatches_DragEnter);
            this.treeViewWatches.DragOver += new System.Windows.Forms.DragEventHandler(this.treeViewWatches_DragOver);
            this.treeViewWatches.KeyDown += new System.Windows.Forms.KeyEventHandler(this.treeViewWatches_KeyDown);
            // 
            // panelAddWatch
            // 
            this.panelAddWatch.Controls.Add(this.textBoxAddWatch);
            this.panelAddWatch.Controls.Add(this.labelAddWatch);
            this.panelAddWatch.Dock = System.Windows.Forms.DockStyle.Bottom;
            this.panelAddWatch.Location = new System.Drawing.Point(0, 242);
            this.panelAddWatch.Name = "panelAddWatch";
            this.panelAddWatch.Size = new System.Drawing.Size(717, 39);
            this.panelAddWatch.TabIndex = 1;
            // 
            // textBoxAddWatch
            // 
            this.textBoxAddWatch.Dock = System.Windows.Forms.DockStyle.Bottom;
            this.textBoxAddWatch.Location = new System.Drawing.Point(0, 19);
            this.textBoxAddWatch.Name = "textBoxAddWatch";
            this.textBoxAddWatch.Size = new System.Drawing.Size(717, 20);
            this.textBoxAddWatch.TabIndex = 1;
            this.textBoxAddWatch.KeyDown += new System.Windows.Forms.KeyEventHandler(this.textBoxAddWatch_KeyDown);
            // 
            // labelAddWatch
            // 
            this.labelAddWatch.AutoSize = true;
            this.labelAddWatch.Location = new System.Drawing.Point(3, 3);
            this.labelAddWatch.Name = "labelAddWatch";
            this.labelAddWatch.Size = new System.Drawing.Size(64, 13);
            this.labelAddWatch.TabIndex = 0;
            this.labelAddWatch.Text = "Add Watch:";
            // 
            // contextMenuStripUserWatch
            // 
            this.contextMenuStripUserWatch.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
            this.addUserWatchToolStripMenuItem,
            this.removeWatchToolStripMenuItem,
            this.clearAllWatchesToolStripMenuItem});
            this.contextMenuStripUserWatch.Name = "contextMenuStripWatch";
            this.contextMenuStripUserWatch.Size = new System.Drawing.Size(167, 70);
            // 
            // addUserWatchToolStripMenuItem
            // 
            this.addUserWatchToolStripMenuItem.Name = "addUserWatchToolStripMenuItem";
            this.addUserWatchToolStripMenuItem.Size = new System.Drawing.Size(166, 22);
            this.addUserWatchToolStripMenuItem.Text = "Add User Watch";
            this.addUserWatchToolStripMenuItem.Click += new System.EventHandler(this.addUserWatchToolStripMenuItem_Click);
            // 
            // removeWatchToolStripMenuItem
            // 
            this.removeWatchToolStripMenuItem.Name = "removeWatchToolStripMenuItem";
            this.removeWatchToolStripMenuItem.Size = new System.Drawing.Size(166, 22);
            this.removeWatchToolStripMenuItem.Text = "Remove Watch";
            this.removeWatchToolStripMenuItem.Click += new System.EventHandler(this.removeWatchToolStripMenuItem_Click);
            // 
            // clearAllWatchesToolStripMenuItem
            // 
            this.clearAllWatchesToolStripMenuItem.Name = "clearAllWatchesToolStripMenuItem";
            this.clearAllWatchesToolStripMenuItem.Size = new System.Drawing.Size(166, 22);
            this.clearAllWatchesToolStripMenuItem.Text = "Clear All Watches";
            this.clearAllWatchesToolStripMenuItem.Click += new System.EventHandler(this.clearAllWatchesToolStripMenuItem_Click);
            // 
            // UserWatchPanel
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.ClientSize = new System.Drawing.Size(717, 281);
            this.Controls.Add(this.panelAddWatch);
            this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
            this.Name = "UserWatchPanel";
            this.Controls.SetChildIndex(this.panelAddWatch, 0);
            this.Controls.SetChildIndex(this.treeViewWatches, 0);
            this.panelAddWatch.ResumeLayout(false);
            this.panelAddWatch.PerformLayout();
            this.contextMenuStripUserWatch.ResumeLayout(false);
            this.ResumeLayout(false);

        }

        private void textBoxAddWatch_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Return)
            {
                UnrealDebuggerIDE.Commands.AddWatch(textBoxAddWatch.Text);
                textBoxAddWatch.Text = "";
            }
        }

        private void treeViewWatches_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Back || e.KeyCode == Keys.Delete)
            {
                TreeNodeAdv node = this.treeViewWatches.CurrentNode;
                WatchNode watch = node != null && node.Level == 1 ? node.Tag as WatchNode : null;

                if (watch != null)
                {
                    UnrealDebuggerIDE.Commands.RemoveWatch(watch.Variable);
                    watch.Parent = null;
                }
            }
        }

        private void treeViewWatches_DragDrop(object sender, DragEventArgs e)
        {
            DataObject data = e.Data as DataObject;
            if (data != null && data.ContainsText())
            {
                UnrealDebuggerIDE.Commands.AddWatch(data.GetText());
            }
        }

        private void treeViewWatches_DragEnter(object sender, DragEventArgs e)
        {
            e.Effect = DragDropEffects.None;

            if ((e.AllowedEffect & DragDropEffects.Copy) == DragDropEffects.Copy)
            {
                DataObject data = e.Data as DataObject;
                if (data != null && data.ContainsText())
                {
                    e.Effect = DragDropEffects.Copy;
                }
            }
        }

        private void treeViewWatches_DragOver(object sender, DragEventArgs e)
        {
            e.Effect = DragDropEffects.Copy;
        }

        private void addUserWatchToolStripMenuItem_Click(object sender, EventArgs e)
        {
            AddUserWatchFromNode(this.treeViewWatches.SelectedNode);
        }

        private void removeWatchToolStripMenuItem_Click(object sender, EventArgs e)
        {
            TreeNodeAdv node = this.treeViewWatches.SelectedNode;
            WatchNode watch = node != null && node.Level == 1 ? node.Tag as WatchNode : null;

            if (watch != null)
            {
                UnrealDebuggerIDE.Commands.RemoveWatch(watch.Variable);
                watch.Parent = null;
            }
        }

        private void clearAllWatchesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            _userWatches = "";
            UnrealDebuggerIDE.Commands.ClearWatches();
            this.ClearAWatch();
        }
    }
}
